import React, { Component } from 'react';
import { connect } from 'dva';
import { Table, Icon, Dropdown, Menu, Modal, Form, Input } from 'antd';
import {
  isArray, isObject, isEmpty, omit,
  cloneDeep, filter, findIndex, isFunction, map,
} from 'lodash';
import ObjectBox from '/common/componentsTpl/ObjectBox';
import ComboBox from '/common/componentsTpl/ComboBox';
import { comboTypes } from '@/globalConfig';

const styles = {
  cursor: 'pointer',
};

const FormItem = Form.Item;
const EditableContext = React.createContext();
const EditableRow = ({ form, index, ...props }) => (
  <EditableContext.Provider value={form}>
    <tr {...props} />
  </EditableContext.Provider>
);
const EditableFormRow = Form.create()(EditableRow);

export default class DataTable extends Component {
  constructor(props) {
    super(props);
    this.state = { data: [] };
  }

  static defaultProps = {
    moreSetting: false,
  };

  componentDidMount() {
    const { dataSource } = this.props;
    this.setState({
      data: cloneDeep(dataSource),
    });
  }

  updateDataCb(data) {
    isFunction(this.props.callUpdateDataFun) &&
    this.props.callUpdateDataFun(data);
  }

  handleSave = (row) => {
    const newData = [...this.state.data];
    const index = newData.findIndex(item => row.key === item.key);
    const item = newData[index];
    newData.splice(index, 1, {
      ...item,
      ...row,
    });
    this.setState({ data: newData });
  };

  filterCol(columns) {
    const { dispatch, global } = this.props;
    return columns.map((col) => {
      if (!col.editable) {
        return col;
      }
      return {
        ...col,
        onCell: record => ({
          record,
          global,
          dispatch,
          editable: col.editable,
          dataIndex: col.dataIndex,
          title: col.title,
          comptype: col.compType ? col.compType : 'input',
          compkey: col.compKey ? col.compKey : '',
          namekey: col.nameKey,
          datatype: col.dataType,
          handleSave: this.handleSave,
        }),
      };
    });
  }


  render() {
    const { compSetting, columns, moreSetting } = this.props;
    const { data } = this.state;
    let columnsT = cloneDeep(columns);
    if (moreSetting) {
      const editRow = ({ key, record }) => {
        let len = isArray(data) ? data.length : 0,
          curIndex = findIndex(data, (o) => {
            return o.key == record.key;
          }),
          tempArr = cloneDeep(data),
          setArrInd = (arr, ind1, ind2) => {
            return arr.splice(ind2, 1, arr[ind1])[0];
          };
        if ('delete' == key) {
          Modal.confirm({
            title: '删除信息',
            content: '确定删除该信息吗？',
            okText: '确认',
            cancelText: '取消',
            onOk: () => {
              tempArr = filter(data, (o) => {
                return o.key != record.key;
              });
              this.setState({
                data: tempArr,
              });
              this.updateDataCb(tempArr);
            },
          });
          return true;
        } else if ('up' == key) {
          if (curIndex > 0 && curIndex < len) {
            tempArr[curIndex] = setArrInd(tempArr, curIndex, curIndex - 1);
          }
        } else if ('down' == key) {
          if (curIndex < len) {
            tempArr[curIndex] = setArrInd(tempArr, curIndex, curIndex + 1);
          }
        } else if ('add' == key || key == 'inner') {
          let tempObj = {};
          for (let o in record) {
            tempObj[o] = 'key' == o ? (len + 1) : null;
          }
          if (curIndex == len && 'add' == key) {
            tempArr.push(tempObj);
          } else if (curIndex == 0 && 'inner' == key) {
            tempArr.unshift(tempObj);
          } else {
            'add' == key ? (tempArr.splice((curIndex + 1), 0, tempObj)) : (tempArr.splice(curIndex, 0, tempObj));
          }
        }
        this.setState({
          data: tempArr,
        });
        this.updateDataCb(tempArr);
      };
      if (columnsT && isArray(columnsT)) {
        columnsT.push({
          style: { padding: 12 },
          dataIndex: 'move',
          key: 'move',
          width: '1px',
          fixed: 'right',
          render: (_, record) => {
            return <Dropdown
              overlay={
                <Menu onClick={({ key }) => editRow({ key, record })}>
                  <Menu.Item key="up">上移行</Menu.Item>
                  <Menu.Item key="down">下移行</Menu.Item>
                  <Menu.Item key="add">添加行</Menu.Item>
                  <Menu.Item key="inner">插入行</Menu.Item>
                  <Menu.Item key="delete">删除行</Menu.Item>
                </Menu>}
              trigger={['click']}
            >
              <span style={styles}>
                <Icon type="setting"/>
              </span>
            </Dropdown>;
          },
        });
      }
    }


    const components = {
      body: {
        row: EditableFormRow,
        cell: EditableCell,
      },
    };
    const col = this.filterCol(columnsT);
    return <Table
      components={components}
      {...omit(this.props, ['compSetting'])}
      columns={col}
      dataSource={data}
    />;
  }
}


//编辑列设置
class EditableCell extends Component {
  state = {
    editing: false,
  };

  toggleEdit = () => {
    const editing = !this.state.editing,
      { compType } = this.props;
    this.setState({ editing }, () => {
      if (editing) {
        if ('input' == compType) {
          this.input.focus();
        }
      }
    });
  };

  save = (e) => {
    const { record, handleSave, dataIndex, datatype } = this.props;
    this.form.validateFields((error, values) => {
      if (error && error[e.currentTarget.id]) {
        return;
      }


      if (values[dataIndex] &&
        isObject(values[dataIndex])) {
        if (!values[dataIndex]['id']) {
          values = record[dataIndex];
        }

        //如果是科目编码
        //if('code' == dataIndex){
        //  values['accounting_item'] = values[dataIndex];
        //}
        ////如果是科目名称
        //if('accounting_item' == dataIndex){
        //  values['code'] = values[dataIndex];
        //}


        //
        //console.log('values:',values);
      }
      this.toggleEdit();
      handleSave({ ...record, ...values });
    });
  };

  getFieldsComp(form) {

    const { record, comptype, title, dataIndex, compkey, global, dispatch, namekey, datatype } = this.props;

    let comp = (<Input
      ref={node => (this.input = node)}
      onPressEnter={this.save}
      onBlur={this.save}
    />);
    if ('select' == comptype && compkey) {
      const nativeProps = {
        onBlur: this.save,
        onPressEnter: this.save,
      };
      const settingProps = {
        nativeProps: nativeProps,
        dispatch: dispatch,
        appCode: comboTypes[compkey],
        compData: global[comboTypes[compkey]],
      };
      if (namekey && !isEmpty(namekey)) {
        settingProps['nameKey'] = namekey;
      }

      if (datatype == 'object') {
        comp = (
          <ObjectBox {...settingProps}/>
        );
      } else if (datatype == 'enum') {
        settingProps['comboType'] = compkey;
        comp = (
          <ComboBox {...settingProps}/>
        );
      }

    }
    return (
      <FormItem style={{ margin: 0 }}>
        {form.getFieldDecorator(dataIndex, {
          rules: [{
            required: true,
            message: `${comptype == 'select' ? '请选择' : '请输入'}${title}`,
          }],
          initialValue: record[dataIndex],
        })(comp)}
      </FormItem>
    );
  }


  render() {
    const {
      editable,
      dataIndex,
      handleSave,
      dispatch, ...restProps
    } = this.props;
    const { editing } = this.state;
    //console.log(1111);
    return (
      <td {...restProps}>
        {editable ? (
          <EditableContext.Consumer>
            {(form) => {
              this.form = form;
              return (
                editing ? (
                  this.getFieldsComp(form)
                ) : (
                  <div
                    className="editable-cell-value-wrap"
                    style={{ paddingRight: 24, minHeight: 30, cursor: 'pointer' }}
                    onClick={this.toggleEdit}
                  >
                    {restProps.children}
                  </div>
                )
              );
            }}
          </EditableContext.Consumer>
        ) : restProps.children}
      </td>
    );
  }
}



